from flask import Blueprint, request, jsonify
from typing import List, Dict
import sys
import os

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from models import db, SentencePair, Favorite
from utils.text_retriever import TextRetriever, format_search_results, paginate_results
from utils.text_auth import token_required
from sqlalchemy.exc import IntegrityError

# 创建蓝图
retrieve_bp = Blueprint('retrieve', __name__)


@retrieve_bp.route('/search', methods=['GET'])
def search_text():
    """
    文本搜索接口
    
    查询参数:
        keyword: 搜索关键词（必填）
        search_type: 搜索类型，'simple' 或 'advanced'，默认为 'simple'
        lang1: 第一种语言代码（可选）
        lang2: 第二种语言代码（可选）
        threshold: 相似度阈值，默认为 0.1
        page: 页码，默认为 1
        per_page: 每页数量，默认为 10
    
    返回:
        JSON格式的搜索结果
    """
    try:
        # 获取查询参数
        keyword = request.args.get('keyword', '').strip()
        search_type = request.args.get('search_type', 'simple').lower()
        lang1 = request.args.get('lang1')
        lang2 = request.args.get('lang2')
        threshold = float(request.args.get('threshold', 0.1))
        page = int(request.args.get('page', 1))
        per_page = int(request.args.get('per_page', 10))
        
        # 参数验证
        if not keyword:
            raise ValueError('搜索关键词不能为空')
        
        if search_type not in ['simple', 'advanced']:
            raise ValueError('搜索类型无效，只能是 simple 或 advanced')
        
        # 从数据库获取句子对数据 - 搜索所有状态的句子对
        query = SentencePair.query
        
        # 语言筛选
        if lang1:
            query = query.filter_by(lang1=lang1)
        if lang2:
            query = query.filter_by(lang2=lang2)
        
        # 执行查询
        sentences = query.all()
        
        # 转换为字典列表
        sentences_list = []
        for sentence in sentences:
            sentences_list.append({
                'id': sentence.id,
                'lang1': sentence.lang1,
                'text1': sentence.text1,
                'lang2': sentence.lang2,
                'text2': sentence.text2,
                'source': sentence.source,
                'created_at': sentence.created_at.isoformat() if sentence.created_at else None
            })
        
        # 创建检索器实例
        retriever = TextRetriever()
        
        # 执行搜索
        if search_type == 'simple':
            search_results = retriever.simple_search(keyword, sentences_list, threshold=threshold)
        else:
            search_results = retriever.advanced_search(keyword, sentences_list, threshold=threshold)
        
        # 格式化结果
        formatted_results = format_search_results(search_results)
        
        # 分页处理
        paginated_data = paginate_results(formatted_results, page=page, per_page=per_page)
        
        # 返回结果
        return jsonify({
            'results': paginated_data['results'],
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'per_page': paginated_data['per_page'],
            'total_pages': paginated_data['total_pages'],
            'keyword': keyword,
            'search_type': search_type
        }), 200
        
    except ValueError as e:
        # 参数错误
        return jsonify({'error': f'参数错误: {str(e)}'}), 400
    except Exception as e:
        # 服务器错误
        print(f'搜索时发生错误: {str(e)}')
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500


@retrieve_bp.route('/stats', methods=['GET'])
def get_retrieve_stats():
    """
    获取检索统计信息
    
    返回:
        JSON格式的统计信息，包括句子对总数和语言分布统计
    """
    try:
        # 获取数据库中的句子对总数
        total_pairs = SentencePair.query.count()
        
        # 获取已批准的句子对数量
        approved_pairs = SentencePair.query.filter_by(status='approved').count()
        
        # 获取不同语言组合的统计
        lang_stats = db.session.query(
            SentencePair.lang1,
            SentencePair.lang2,
            db.func.count(SentencePair.id)
        ).group_by(SentencePair.lang1, SentencePair.lang2).all()
        
        language_stats = [
            {
                'lang1': stat[0],
                'lang2': stat[1],
                'count': stat[2]
            }
            for stat in lang_stats
        ]
        
        # 获取数据源统计
        source_stats = db.session.query(
            SentencePair.source,
            db.func.count(SentencePair.id)
        ).group_by(SentencePair.source).all()
        
        source_data = [
            {
                'source': stat[0],
                'count': stat[1]
            }
            for stat in source_stats
        ]
        
        return jsonify({
            'total_pairs': total_pairs,
            'approved_pairs': approved_pairs,
            'language_stats': language_stats,
            'source_stats': source_data
        }), 200
        
    except Exception as e:
        print(f'获取统计信息错误: {str(e)}')
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500


@retrieve_bp.route('/languages', methods=['GET'])
def get_available_languages():
    """
    获取系统中可用的语言列表
    
    返回:
        JSON格式的语言列表
    """
    try:
        # 查询所有不同的语言代码
        lang1_results = db.session.query(SentencePair.lang1).distinct().all()
        lang2_results = db.session.query(SentencePair.lang2).distinct().all()
        
        # 合并并去重
        languages = set()
        for result in lang1_results:
            if result[0]:
                languages.add(result[0])
        for result in lang2_results:
            if result[0]:
                languages.add(result[0])
        
        # 构建语言信息列表
        language_list = []
        language_names = {
            'zh': '中文',
            'vi': '越南语',
            'th': '泰语',
            'ms': '马来语',
            'id': '印尼语',
            'tl': '塔加洛语',
            'km': '高棉语',
            'lo': '老挝语',
            'my': '缅甸语',
            'si': '僧伽罗语'
        }
        
        for lang_code in sorted(languages):
            language_list.append({
                'code': lang_code,
                'name': language_names.get(lang_code, lang_code)
            })
        
        return jsonify({
            'languages': language_list,
            'total': len(language_list)
        }), 200
        
    except Exception as e:
        print(f'获取语言列表错误: {str(e)}')
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500


# ==================== 收藏功能API ====================

@retrieve_bp.route('/favorites', methods=['POST'])
@token_required
def add_favorite(current_user):
    """
    添加收藏
    
    请求体:
        sentence_pair_id: 句子对ID（必填）
    
    返回:
        JSON格式的收藏记录
    """
    try:
        # 获取当前用户ID
        current_user_id = current_user.id
        
        # 获取请求数据
        data = request.json
        if not data:
            return jsonify({'status': 'error', 'message': '请求数据不能为空'}), 400
        
        sentence_pair_id = data.get('sentence_pair_id')
        if not sentence_pair_id:
            return jsonify({'status': 'error', 'message': '句子对ID不能为空'}), 400
        
        # 检查句子对是否存在
        sentence_pair = SentencePair.query.get(sentence_pair_id)
        if not sentence_pair:
            return jsonify({'status': 'error', 'message': '句子对不存在'}), 404
        
        # 检查是否已收藏
        existing_favorite = Favorite.query.filter_by(
            user_id=current_user_id,
            sentence_pair_id=sentence_pair_id
        ).first()
        
        if existing_favorite:
            return jsonify({'status': 'error', 'message': '已经收藏过该内容'}), 400
        
        # 创建收藏记录
        favorite = Favorite(
            user_id=current_user_id,
            sentence_pair_id=sentence_pair_id
        )
        
        db.session.add(favorite)
        db.session.commit()
        
        return jsonify({
            'status': 'success',
            'data': {
                'id': favorite.id,
                'user_id': favorite.user_id,
                'sentence_pair_id': favorite.sentence_pair_id,
                'created_at': favorite.created_at.isoformat() if favorite.created_at else None
            }
        }), 201
        
    except IntegrityError:
        db.session.rollback()
        return jsonify({'status': 'error', 'message': '收藏失败，该内容可能已被收藏'}), 400
    except Exception as e:
        db.session.rollback()
        print(f'添加收藏错误: {str(e)}')
        return jsonify({'status': 'error', 'message': f'服务器内部错误: {str(e)}'}), 500


@retrieve_bp.route('/favorites/<int:favorite_id>', methods=['DELETE'])
@token_required
def remove_favorite(current_user, favorite_id):
    """
    取消收藏（按收藏ID）
    
    路径参数:
        favorite_id: 收藏记录ID
    
    返回:
        JSON格式的成功消息
    """
    try:
        # 获取当前用户ID
        current_user_id = current_user.id
        
        # 查找收藏记录
        favorite = Favorite.query.filter_by(
            id=favorite_id,
            user_id=current_user_id
        ).first()
        
        if not favorite:
            return jsonify({'status': 'error', 'message': '收藏记录不存在或无权删除'}), 404
        
        # 删除收藏
        db.session.delete(favorite)
        db.session.commit()
        
        return jsonify({
            'status': 'success',
            'message': '取消收藏成功'
        }), 200
        
    except Exception as e:
        db.session.rollback()
        print(f'取消收藏错误: {str(e)}')
        return jsonify({'status': 'error', 'message': f'服务器内部错误: {str(e)}'}), 500


@retrieve_bp.route('/favorites/pair/<int:pair_id>', methods=['DELETE'])
@token_required
def remove_favorite_by_pair(current_user, pair_id):
    """
    取消收藏（按句子对ID）
    
    路径参数:
        pair_id: 句子对ID
    
    返回:
        JSON格式的成功消息
    """
    try:
        # 获取当前用户ID
        current_user_id = current_user.id
        
        # 查找收藏记录
        favorite = Favorite.query.filter_by(
            user_id=current_user_id,
            sentence_pair_id=pair_id
        ).first()
        
        if not favorite:
            return jsonify({'status': 'error', 'message': '未收藏该内容'}), 404
        
        # 删除收藏
        db.session.delete(favorite)
        db.session.commit()
        
        return jsonify({
            'status': 'success',
            'message': '取消收藏成功'
        }), 200
        
    except Exception as e:
        db.session.rollback()
        print(f'取消收藏错误: {str(e)}')
        return jsonify({'status': 'error', 'message': f'服务器内部错误: {str(e)}'}), 500


@retrieve_bp.route('/favorites', methods=['GET'])
@token_required
def get_favorites(current_user):
    """
    获取用户收藏列表
    
    查询参数:
        page: 页码，默认为 1
        per_page: 每页数量，默认为 10
    
    返回:
        JSON格式的收藏列表（包含句子对详细信息）
    """
    try:
        # 获取当前用户ID
        current_user_id = current_user.id
        
        # 获取分页参数
        page = int(request.args.get('page', 1))
        per_page = int(request.args.get('per_page', 10))
        
        # 查询用户的收藏（关联句子对信息）
        favorites_query = Favorite.query.filter_by(user_id=current_user_id)\
            .order_by(Favorite.created_at.desc())
        
        # 分页
        pagination = favorites_query.paginate(page=page, per_page=per_page, error_out=False)
        
        # 构建语言映射表
        language_names = {
            'zh': '中文',
            'vi': '越南语',
            'en': '英语',
            'th': '泰语',
            'ms': '马来语',
            'id': '印尼语',
            'tl': '塔加洛语',
            'km': '高棉语',
            'lo': '老挝语',
            'my': '缅甸语',
            'si': '僧伽罗语'
        }

        # 构建返回数据
        favorites_list = []
        for favorite in pagination.items:
            sentence_pair = favorite.sentence_pair
            if sentence_pair:
                favorites_list.append({
                    'favorite_id': favorite.id,
                    'sentence_pair_id': sentence_pair.id,
                    'lang1': sentence_pair.lang1,
                    'text1': sentence_pair.text1,
                    'lang2': sentence_pair.lang2,
                    'text2': sentence_pair.text2,
                    'source': sentence_pair.source,
                    'created_at': favorite.created_at.isoformat() if favorite.created_at else None,
                    # 添加语言显示名称
                    'lang1_display': language_names.get(sentence_pair.lang1, sentence_pair.lang1 or ''),
                    'lang2_display': language_names.get(sentence_pair.lang2, sentence_pair.lang2 or '')
                })
        
        return jsonify({
            'status': 'success',
            'data': {
                'favorites': favorites_list,
                'total': pagination.total,
                'page': pagination.page,
                'per_page': pagination.per_page,
                'total_pages': pagination.pages
            }
        }), 200
        
    except Exception as e:
        print(f'获取收藏列表错误: {str(e)}')
        return jsonify({'status': 'error', 'message': f'服务器内部错误: {str(e)}'}), 500


@retrieve_bp.route('/favorites/batch-check', methods=['POST'])
@token_required
def batch_check_favorites(current_user):
    """
    批量检查收藏状态
    
    请求体:
        sentence_pair_ids: 句子对ID列表
    
    返回:
        JSON格式的已收藏ID列表
    """
    try:
        # 获取当前用户ID
        current_user_id = current_user.id
        
        # 获取请求数据
        data = request.json
        if not data:
            return jsonify({'status': 'error', 'message': '请求数据不能为空'}), 400
        
        sentence_pair_ids = data.get('sentence_pair_ids', [])
        if not sentence_pair_ids or not isinstance(sentence_pair_ids, list):
            return jsonify({'status': 'error', 'message': '句子对ID列表格式错误'}), 400
        
        # 查询已收藏的ID
        favorites = Favorite.query.filter(
            Favorite.user_id == current_user_id,
            Favorite.sentence_pair_id.in_(sentence_pair_ids)
        ).all()
        
        favorited_ids = [f.sentence_pair_id for f in favorites]
        
        return jsonify({
            'status': 'success',
            'data': {
                'favorited_ids': favorited_ids
            }
        }), 200
        
    except Exception as e:
        print(f'批量检查收藏状态错误: {str(e)}')
        return jsonify({'status': 'error', 'message': f'服务器内部错误: {str(e)}'}), 500